home *** CD-ROM | disk | FTP | other *** search
- ******************
- * *
- * CLOCKSET.ASM * Set Time of Clock Cartridge
- * * <=> PUBLIC DOMAIN 09-SEP-86 <=>
- ******************
- *
- *** created: 03-AUG-86 by Tim Hunkler / Solar Powered Software
- *
- ROM3 equ $FA0000 ; ROM3 select strobe
- ROM4 equ $FB0000 ; ROM4 select strobe
- READ equ 0 ; control for READ access (A6=0)
- WRT equ 64 ; control for WRITE access (A6=1)
- *
- * --- Function call definitions for GEM/AES calls
- *
- APPL_INI equ 0 ; Application initialization
- APPL_EXI equ 1 ; Application exit
- OBJC_DRA equ 2 ; Object draw
- FORM_DO equ 3 ; Form: Do
- FORM_DIA equ 4 ; Form: Dialog
- FORM_ALE equ 5 ; Form: Alert
- FORM_CEN equ 6 ; Form: Center
- GRAF_MOU equ 7 ; Graphics: Mouse Form
- *
- * --- Offset definitions for dynamic storage
- *
- params equ $0000 ; table of array pointers
- control equ $0018 ; array of control counts
- global equ $0022 ; array of global variables
- int_in equ $0040 ; array of integers in
- int_out equ $0060 ; array of integers out
- addr_in equ $006E ; array of addresses in
- addr_out equ $0072 ; array of addresses out
- buffer equ $0076 ; buffer to receive clock chip data
- ap_id equ $0026 ; application ID, one of the globals
- stack equ $0486 ; stack area (grows downward)
- xx equ $048A ; temp area to receive x,y,w,h info
- sz_stor equ $0492 ; size of dynamic storage needs
-
- * ===============================
- * ----- PROGRAM ENTRY POINT -----
- * ===============================
-
- x: lea storage(pc),a5 ; load base of dynamic storage
- lea stack(a5),sp ; establish a stack
- *
- * --- release all memory not needed
- *
- move.l #(storage-x+256+sz_stor),-(sp) ; push num bytes to keep
- pea x-256(pc) ; push address of memory to keep
- clr.w -(sp) ; push filler
- move.w #74,-(sp) ; push function code = memory shrink
- trap #1 ; call the system
- lea 12(sp),sp ; fix the stack
- *
- * --- initialize GEM/AES parameter block
- *
- lea params+24(a5),a6 ; address end of block
- lea control(a5),a0 ; first pntr
- lea global(a5),a1 ; second pntr
- lea int_in(a5),a2 ; third pntr
- lea int_out(a5),a3 ; fourth pntr
- lea addr_in(a5),a4 ; fifth pntr
- lea addr_out(a5),a5 ; sixth pntr
- movem.l a0-a5,-(a6) ; fill data block
- *
- * --- zero some areas in =global=
- *
- moveq #14,d0 ; loop for 15 words
- zgbl: clr.w (a1)+ ; clear entire array
- dbf d0,zgbl
- *
- * --- initialize base and data pointers and start program
- *
- lea x(pc),a6 ; A6 will be program base register
- lea storage(pc),a5 ; A5 will be data storage base register
- *
- * --- begin regular program code
- *
- START: bsr _appl_in ; initialize application
- bsr _mouse ; change mouse pointer to an arrow
- *
- * --- read info from the clock cartridge
- *
- rdcart: lea buffer(a5),a2 ; load addr of buffer to be filled
- bsr r_clock ; read time from the clock cartridge
- beq.s hwok ; branch if all went ok
- *
- * --- clock's time was bad or the hardware is not working
- *
- lea warning(pc),a0 ; address warning message
- bsr _alert ; and display the message
- *
- * --- process dialog menu
- *
- hwok: bsr format ; format time/date into dialog strings
- bsr dialog ; display and process the dialog
- *
- * --- determine which exit button was used
- *
- moveq #1,d3 ; outer box = object #1
- bsr tstnclr ; was outer box selected?
- bne.s rdcart ; yes, then update the time displayed
-
- moveq #12,d3 ; SET = object #12
- bsr tstnclr ; was SET button selected?
- beq.s if13 ; no, branch
- bsr set_clk ; yes, change time
- bra.s rdcart
-
- if13: bsr tstnclr ; was button = EXIT?
- beq.s rdcart ; no, then update menu
- *
- * --- exit this program
- *
- bsr _appl_ex ; notify GEM of application exit
-
- clr.w -(sp) ; function code = exit
- trap #1 ; call TOS and never return!
-
- * =====================================
- * ===== w_clock : write to clock =====
- * =====================================
- *
- * in: D0.B = data to be written
- * D1.W = register address x 2 to be written to
- *
- * out: A3.L = pointer to clock address latch
- * A4.L = pointer to clock chip select
- * D1.W = increased by 2
- * D0.W = data present prior to write
- * cc's : set by D0
- *
- * changed: A0,D2
- *
- * This subroutine is used to write data to the clock chip. The data
- * to be written is passed in the lower 4 bits of D0 and 2 times the
- * clock register to be accessed in passed in D1.
- *
- w_clock:
- lea ROM3,a3 ; LATCH address
- lea ROM4,a4 ; CS low strobe
- *
- * --- form the clock register address
- *
- wcep: lea 0(a3,d1.w),a0 ; form proper address
- *
- * --- mask off 4 bit data and align it into bits 12..15
- *
- moveq #15,d2 ; load mask
- and.w d0,d2 ; mask of 4 bit data item
- ror.w #4,d2 ; rotate to upper bits
- *
- * --- latch address, data, and enable writes to the chip
- *
- move.b WRT(a0,d2.l),d0 ; read old data, latch new data
- *
- * --- turn chip select on to start the write operation
- *
- tst.w (a4) ; set chip select low
- addq.w #2,d1 ; update register address
- *
- * --- turn off write enable, turn off chip select, but hold data
- *
- tst.b READ(a0,d2.l) ; set chip select high
- andi.w #$000F,d0 ; mask off 4 bit data and set cond codes
- rts
-
- * =====================================
- * ===== r_clock : read from clock =====
- * =====================================
- *
- * in: A2.L = address of 16 byte buffer to be filled
- *
- * out: D0.L = 0 if all OK, else -1
- * cc's : set by D0
- * (A2) ---> [ flag bits ] leap count, AM/PM, 12/24 hr.
- * +1 [ day of week ] 1=Sunday
- * +2 [ year x 10 ] 00 = 1980, 01 = 1981, etc.
- * +3 [ year x 1 ]
- * +4 [ month x 10 ]
- * +5 [ month x 1 ]
- * [ day x 10 ]
- * [ day x 1 ]
- * [ hour x 10 ]
- * [ hour x 1 ]
- * [ minute x 10 ]
- * [ minute x 1 ]
- * [ second x 10 ]
- * [ second x 1 ]
- * +14 [ .1 seconds ]
- * +15 [ junk byte ]
- *
- * changed: A0,A4,D1,D2
- *
- * This subroutine reads all time and date registers from the clock chip
- * and fills a 16 byte buffer whose address was passed in A2. As the
- * information is read it is added up. Invalid sums typically indicate
- * a dead battery or a clock cartridge which is not present and are
- * indicated by returning a -1 in register D0 and the condition codes.
- * A data changed bit is checked and if the time changed while the read
- * operation was in progress the operation is repeated.
- *
- r_clock:
- lea ROM4,a4 ; set pointer for ROM4 strobe
- lea ROM3,a0 ; set pntr to register 0
- lea 16(a2),a2 ; point to end of buffer to fill
- moveq #0,d1 ; set accumulator to zero
- *
- * --- preload the register address in the latch
- *
- tst.w (a0)+ ; set register selection to 0
- *
- * --- loop and read clock registers 0..15
- *
- moveq #15,d2 ; loop count = 16
- fetch: tst.w (a4) ; set chip select on
- moveq #15,d0 ; load 4 bit data mask
- and.w (a0)+,d0 ; get data, set next addr, select off
- move.b d0,-(a2) ; store data in buffer
- add.w d0,d1 ; add up all data values
- dbf d2,fetch ; and repeat for 16 items
- *
- * --- retrieve data changed flag (zero indicates no change occurred)
- *
- tst.w (a4) ; set CS low with register select = 0
- moveq #8,d0 ; load mask
- and.w (a0),d0 ; get flag, nxt addr = 2, select = off
- *
- * --- if no clock present we generally accumulate 16 x 15 = 240
- *
- cmpi.w #125,d1 ; does accumulation indicate bad data?
- ble.s nwflg ; no, branch
- moveq #-1,d0 ; yes, set error flag
- *
- * --- test data changed flag and reread the time if necessary
- *
- nwflg: tst.w d0 ; was data changed (or an error)?
- bgt.s r_clock ; yes, then repeat the time reading
- rts ; no, exit with cond codes set
-
- * =========================================================
- * ===== format: format clock data buffer into dialog =====
- * =========================================================
- *
- * in: A2.L = addr of 16 byte buffer returned by "r_clock"
- * out: none
- * changed: A0,A1,A2,A3,D0,D1,D2,D3
- *
- * This subroutine takes the contents of the 16 byte buffer filled
- * in by "r_clock" and uses it to format information in the dialog
- * menu. The 7 radio buttons which indicate the day of the week are
- * set based on the day of the week value of 1..7. The date is
- * formatted and the date string is formed. And also the time is
- * formatted and the time string is formed.
- *
- format: lea tree(pc),a3 ; address dialog tree
- *
- * --- clear radio buttons
- *
- moveq #6,d2 ; loop for 7 days of the week
- moveq #5,d3 ; start with button for SUN
- fmtclr: bsr tstnclr ; clear buttons for SUN..SAT
- dbra d2,fmtclr ; repeat till done
- *
- * --- set radio button for day of the week
- *
- moveq #7,d3 ; load 3 bit mask
- and.w (a2)+,d3 ; get day of week, 1..7
- addq.w #4,d3 ; convert to object number 5..11
- bsr setsel ; set button for SUN..SAT
- *
- * --- form date string: MM/DD/YY
- *
- lea s_date+4(pc),a1 ; access date string
- move.b (a2)+,(a1) ; copy tens digit of year
- addi.b #8,(a1)+ ; modify for 1980 baseline
- move.b (a2)+,(a1)+ ; copy ones digit of year
-
- subq.l #6,a1 ; back up to access month
- move.b (a2)+,(a1)+ ; move two digits of month
- move.b (a2)+,(a1)+
-
- move.b (a2)+,(a1)+ ; move two digits of day-of-month
- move.b (a2)+,(a1)+
- *
- * --- form time string: HH:MM:SS AM
- *
- moveq #'A',d2 ; preload AM/PM indicator as AM
- moveq #15,d0 ; load a mask
- and.b (a2)+,d0 ; get tens digit of hour
- mulu #10,d0
- add.b (a2)+,d0 ; add in ones digit, hours in D0.W
-
- lea s_time+2(pc),a1 ; address minute field
- move.b (a2)+,(a1)+ ; move two digits of minutes
- move.b (a2)+,(a1)+
-
- move.b (a2)+,(a1)+ ; move two digits of seconds
- move.b (a2)+,(a1)+
-
- tst.w d0 ; is it midnight to 1:00 am ?
- bne.s ampm ; no, skip ahead
- moveq #12,d0 ; yes, change from 00:xx to 12:xx
- bra.s AM
-
- ampm: cmpi.w #12,d0 ; does hour indicate PM?
- blt.s AM ; for 00:00 to 11:59 no change
- beq.s noon ; for 12:00 to 12:59 change flag to 'PM'
- subi.w #12,d0 ; for 13:00 to 23:59 reduce by 12 hours
- noon: moveq #'P',d2 ; change flag to PM
-
- AM: move.b d2,(a1)+ ; store A or P for AM/PM
-
- subq.l #7,a1 ; point to hours field
- divu #10,d0 ; split hours into tens and ones digit
- move.b d0,(a1)+ ; store tens digit
- swap d0 ; access ones digit
- move.b d0,(a1) ; store ones digit
- subq.l #1,a1 ; adjust pntr to time string
- bsr.s convrt ; convert binary into characters
-
- lea s_date(pc),a1 ; adjust pntr to date string
- convrt: moveq #5,d1 ; do 6 digits
- cvt: ori.b #'0',(a1)+ ; convert byte into ASCII
- dbra d1,cvt
- rts
-
- * =======================================================
- * ===== set_clk : Set time/date in clock cartridge =====
- * =======================================================
- *
- * in: A3.L = address of dialog tree
- * out: none
- * changed:
- *
- * This subroutine uses the time and date present on the dialog
- * menu to set the time and date for GEM and TOS. It then converts
- * this information into the appropriate fields of the 16 byte table
- * filled in by 'r_clock' and uses this table to alter the time and
- * date of the MM58274 clock chip.
- *
- set_clk:
- bsr set_time ; set time for TOS and GEM
- bne.s tsok ; branch if all went ok
-
- lea badtime(pc),a0 ; address error message
- bra _alert ; display alert then return
-
- tsok: lea buffer-1(a5),a2 ; ; access byte prior to buffer
- move.b #1,(a2)+ ; install command = %0001
- clr.b (a2)+ ; install command = %0000
- *
- * --- figure out which day of the week is indicated
- *
- moveq #5,d3 ; select button = SUN
- sfdow: bsr tstnclr ; is it selected?
- beq.s sfdow ; no, then try next button
- subq.w #5,d3 ; convert SUN..SAT into 1..7
- move.b d3,(a2)+ ; and store
- *
- * --- convert the date string into binary nibbles
- *
- lea s_date+4(pc),a0 ; access tens digit of year
- subq.b #8,(a0) ; convert 1980 into 00
- move.b (a0)+,(a2)+ ; move two year digits
- move.b (a0)+,(a2)+
-
- subq.l #6,a0 ; access month
- move.b (a0)+,(a2)+ ; move two month digits
- move.b (a0)+,(a2)+
-
- move.b (a0)+,(a2)+ ; move two day digits
- move.b (a0)+,(a2)+
- *
- * --- convert the time string into binary nibbles
- *
- lea s_time(pc),a0 ; access time string
- bsr conv2dig ; convert hours into binary
-
- cmpi.b #'A',4(a0) ; is AM or PM indicated?
- beq.s nnta ; branch if AM
- cmpi.w #12,d0 ; is hour between 12:00 and 12:59?
- beq.s nnta ; yes, then skip
- addi.w #12,d0 ; adjust 1:00 into 13:00
-
- nnta: divu #10,d0 ; split hours into digits
- move.b d0,(a2)+ ; store tens digit of hours
- swap d0 ; access ones digit
- move.b d0,(a2)+ ; store ones digit of hours
-
- move.b (a0)+,(a2)+ ; move two digits of minutes
- move.b (a0)+,(a2)+
-
- move.b (a0)+,(a2)+ ; move two digits of seconds
- move.b (a0)+,(a2)+
- *
- * --- translate ASCII digits into binary
- *
- moveq #13,d0 ; loop 14 bytes
- xclr: andi.b #15,-(a2) ; convert ASCII digits to binary
- dbra d0,xclr
- *
- * --- begin clock update
- *
- lea buffer+14(a5),a2 ; address end of time data
- moveq #5,d0 ; command = stop clock
- moveq #0,d1 ; address = 0
- bsr w_clock ; write command to stop clock
-
- moveq #1,d0 ; command = set 24 hour mode
- moveq #30,d1 ; addr = 15
- bsr w_clock ; write command
-
- moveq #7,d0 ; command = interrupts off
- moveq #0,d1 ; addr = 0
- bsr w_clock ; write command
- *
- * --- reprogram all registers from the table and start clock
- *
- moveq #14,d3 ; loop for 15 writes
- moveq #4,d1 ; begin addr = 2 (seconds register)
- sb2c: move.b -(a2),d0 ; get next time digit
- bsr w_clock ; change the time
- dbra d3,sb2c
- rts
-
- * ==========================================================
- * ===== conv2dig : convert decimal string into binary =====
- * ==========================================================
- *
- * in: A0.L = address of string
- * out: D0.L = binary value, range = 0..99
- * A0.L = incremented by 2
- * cc's : set by D0
- * changed: D1
- *
- * This subroutine converts the two digit ASCII string pointed to by
- * A0 into a binary value of the range 0..99. The alternate entry
- * point 'tenx' forms D0.L = 10*D0 + D1
- *
- conv2dig:
- moveq #15,d0 ; load mask for ten's digit
- moveq #15,d1 ; load mask for one's digit
- and.b (a0)+,d0 ; retrieve ten's digit
- and.b (a0)+,d1 ; retrieve one's digit
- *
- * --- form the result: 10*D0 + D1
- *
- tenx: add.l d0,d0 ; 2x
- add.l d0,d1 ; form 2x + y
- add.l d0,d0 ; 4x
- add.l d0,d0 ; 8x
- add.l d1,d0 ; result = 8x + 2x + y = 10x + y
- rts
-
- * ========================================
- * ===== chk_time : check time string =====
- * ========================================
- *
- * in: none
- * out: CC's : Z=1 if invalid string
- * changed: a0,a1,d0,d1,d2
- *
- * This subroutine checks the time and date strings of the dialog for
- * valid digits. If any invalid digit is present the condition codes
- * are set accordingly before exit.
- *
- t_vld: dc.w $0003 ; month x 10 = [0..1]
- dc.w $03ff ; month x 1 = [0..9]
- dc.w $000f ; date x 10 = [0..3]
- dc.w $03ff ; date x 1 = [0..9]
- dc.w $0300 ; year x 10 = [8..9]
- dc.w $03ff ; year x 1 = [0..9]
- dc.w -1
- dc.w $0003 ; hour x 10 = [0..1]
- dc.w $03ff ; hour x 1 = [0..9]
- dc.w $003f ; minute x 10 = [0..5]
- dc.w $03ff ; minute x 1 = [0..9]
- dc.w $003f ; second x 10 = [0..5]
- dc.w $03ff ; second x 1 = [0..9]
- *
- chk_time:
- lea s_date(pc),a0 ; address the date string
- lea t_vld(pc),a1 ; point to table
- moveq #11,d2 ; loop count = 6 + 6 digits
- ct: moveq #15,d0 ; load mask
- and.b (a0)+,d0 ; get lower nibble of digit
- move.w (a1)+,d1 ; get validation bits
- bpl.s cx ; branch unless validation = -1
- lea s_time(pc),a0 ; if -1, switch to time string
- bra.s ct ; and continue
-
- cx: btst d0,d1 ; is digit valid?
- dbeq d2,ct ; loop if valid, stop if not
- rts ; return with cc's set
-
- * ===================================
- * ===== set_time : set the time =====
- * ===================================
- *
- * in: none
- * out: none
- * changed:
- *
- * This routine checks the time and date strings of the dialog menu for
- * validity. If the strings are valid the information in them is used
- * to generate the bit formats necessary to tell GEM and TOS what the
- * time and date are. Then the time and date are changed via system
- * calls.
- *
- set_time:
- bsr.s chk_time ; is the time and date valid?
- beq.s stxit ; no, then exit
- *
- * --- convert date into BIOS format
- *
- lea s_date(pc),a0 ; address the date string
- bsr.s conv2dig ; pull off the month
- moveq #$0F,d7 ; load 4 bit mask
- and.w d0,d7 ; 0000 0000 0000 mmmm
-
- bsr.s conv2dig ; pull off the day of the month
- andi.w #$001F,d0 ; mask down to 5 bits
- lsl.w #5,d7 ; shift month bits left
- or.w d0,d7 ; 0000 000m mmmd dddd
-
- bsr conv2dig ; pull off the year
- subi.w #80,d0 ; convert 80 into 00
- andi.w #$007F,d0 ; mask down to 7 bits
- ror.w #7,d0 ; roll year to high end of word
- or.w d0,d7 ; yyyy yyym mmmd dddd
-
- swap d7 ; save 'date' in high order bits of D7
- *
- * --- convert time into BIOS format
- *
- lea s_time(pc),a0 ; address time string
- bsr conv2dig ; get HH
- move.w d0,d7 ; 0000 0000 000h hhhh
-
- bsr conv2dig ; get MM
-
- cmpi.b #'A',(a0) ; are we AM or PM?
- beq.s useAM ; branch if AM
- cmpi.w #12,d7 ; are we 12:xx PM?
- beq.s useAM ; yes, then don't correct
- addi.w #12,d7 ; else convert 1..11 into 13..23
-
- useAM: lsl.w #6,d7 ; shift bits to make room for minutes
- andi.w #$003F,d0 ; mask minutes down to 6 bits
- or.w d0,d7 ; 0000 0hhh hhmm mmmm
- *
- * --- align time and set seconds to zero
- *
- lsl.w #5,d7 ; hhhh hmmm mmm0 0000
- *
- * --- tell GEM what the date and time is
- *
- move.l d7,-(sp) ; pass [date:time] on stack
- move.w #22,-(sp) ; function code
- trap #14 ; tell GEM what date/time is
- addq.l #6,sp ; fix stack
- *
- * --- tell TOS what the time is
- *
- move.w d7,-(sp) ; push "time"
- move.w #45,-(sp) ; function code
- trap #1 ; tell TOS what time is
- addq.l #4,sp ; fix stack
- *
- * --- tell TOS what the date is
- *
- swap d7 ; reorder [date:time] to [time:date]
- move.w d7,-(sp) ; push "date"
- move.w #43,-(sp) ; function code
- trap #1 ; tell TOS what date is
- addq.l #4,sp ; fix stack
-
- moveq #-1,d7 ; set condition codes to indicate OK
- stxit: rts
-
- * ==================================================
- * ===== dialog : display dialog and await exit =====
- * ==================================================
- *
- * in: A3.L = address of tree
- * out: D3.W = object ID causing exit
- * changed: A0, D0, ?
- *
- * This subroutine reserves memory, draws the tree addressed by A3,
- * processes the dialog, erases the dialog, sets the button which caused
- * exit to non-selected, and frees up the reserved memory. The object
- * number of the button which caused exit is returned in D3.
- *
- dialog: bsr rsrv_win ; reserve window space
- bsr treedraw ; draw the tree
- bsr wfbutton ; wait for response
- bra free_win ; erase window
-
- * ==================================================
- * ===== tstnclr : Test and Clear SELECTED bit =====
- * ==================================================
- *
- * in: A3.L = tree address
- * D3.W = object ID
- * out: D3.W = incremented by 1
- * D0.W = object's state word anded with 1
- * cc's : set by D0.W
- * changed: A0
- *
- * This subroutine tests the SELECTED bit of the object number passed in
- * D3 and increments D3. The state of the bit is used to set a
- * condition code before exit.
- *
- tstnclr:
- bsr.s objba ; get address
- moveq #SELECTED,d0 ; load mask
- and.w (a0),d0 ; get bit
- eor.w d0,(a0) ; clear bit if set
- addq.w #1,d3 ; update
- tst.w d0 ; set condition codes
- rts
-
- * ============================================
- * ===== objba : object bit address ========
- * ============================================
- *
- * input: A3.L = address of tree
- * D3.W = object ID
- * out: A0.L = address of object's state word
- * changed: D0
- *
- * This subroutine is used to form the address of the resource object's
- * STATE word when given the resource tree address and object number.
- *
- objba: move.w d3,d0 ; copy object number
- mulu #24,d0 ; form 24 byte offset per object
- lea 10(a3,d0.l),a0 ; STATE word is 10 bytes into object
- rts
-
- * ===========================================
- * ===== objbset : object bit set ===========
- * ===========================================
- *
- * in: A3.L = address of tree
- * D3.W = object id
- * D4.W = bit mask
- * out: A0.L = address of object's state word
- * changed: none
- *
- * This subroutine is used to 'OR' a bit mask with the STATE word of an
- * object in a resource tree. The alternate entry point 'setsel' is
- * used when the 'SELECTED' bit is to be set.
- *
- setsel: moveq #1,d4 ; load SELECTED bit mask
- objbset: bsr.s objba ; form address
- or.w d4,(a0) ; set bits by ORing
- rts
-
- * ==========================================
- * ===== rsrv_win : reserve window ==========
- * ==========================================
- *
- * in: A3.L = address of tree about to be displayed
- * out: none
- * changed: D0,D1,A0,A1
- *
- * This routine first calls the FORM_CENTER routine to set the x,y,w,h
- * needed to center the window. Then control drops into FREE_WIN which
- * reserves the memory needed for the window size
- *
- rsrv_win:
- lea xx(a5),a1 ; addr temp area to receive x,y,w,h
- bsr _form_ce ; calculate window center
- moveq #0,d0 ; pass code for reserving space
- bra.s fwep ; enter free_win routine
-
- * =======================================================
- * ===== free_win : free up memory reserved earlier =====
- * =======================================================
- *
- * in: none
- * out: none
- * changed: D0,D1,A0,A1
- *
- * This subroutine frees up memory which was reserved earlier. The
- * x,y,w,h clip rectangle was earlier stored at 'xx'.
- *
- free_win:
- moveq #3,d0 ; use code = 3,
- fwep: lea xx(a5),a0 ; load pointer to x,y,w,h area
- bra.s _form_di ; free memory
-
- * =====================================
- * ===== objdraw : draw an object =====
- * =====================================
- *
- * in: A3.L = address of tree
- * D3.W = object to start with
- * out: none
- * changed: ?
- *
- * This subroutine draws the resource tree starting at the object number
- * given in D3 and for 5 levels of offspring. The alternate entry point
- * 'treedraw' starts at object number 0 for drawing an entire tree.
- *
- treedraw:
- moveq #0,d3 ; for trees set object number to zero
- objdraw:
- lea xx(a5),a0 ; address x,y,w,h
- moveq #5,d1 ; pass 5 levels
- move.w d3,d0 ; pass object number in d0
- bra _objc_dr ; draw
-
- * ===============================================
- * ===== wfbutton : wait for a button ===========
- * ===============================================
- *
- * in: A3.L = tree address
- * D0.W = object ID of editable text, 0 if none
- * out: D3.W = ID of button causing exit
- * changed: ?
- *
- * This routine calls the FORM_DO routine which processes the user
- * interaction with a dialog. Upon exit the object number which was
- * used to exit the dialog is returned in D3.
- wfbutton:
- moveq #0,d0 ; set object number to 0
- wftext: bsr.s _form_do ; process dialog
- move.w d0,d3 ; assign to exitobj
- rts
-
- * =================================
- * ===== _APPL_IN : initialize =====
- * =================================
- *
- * in: none
- * out: D0.W = ap_id or -1 if error
- * cc's : set by D0.W
- * changed:
- *
- * This routine notifies GEM of an application and allows GEM to set up
- * some housekeeping. An application ID is assigned and we store it
- * in our global variable area.
- *
- _appl_in:
- moveq #APPL_INI,d1 ; code = initialize
- bsr.s gem_ep ; call GEM
- move.w d0,ap_id(a5) ; store application ID
- rts
-
- * ===========================
- * ===== _APPL_EX : exit =====
- * ===========================
- *
- * in: none
- * out: d0.w = 0 on error
- *
- * This routine notifies GEM of our intention to terminate.
- *
- _appl_ex:
- moveq #APPL_EXI,d1 ; code = exit
- bra.s gem_ep ; call GEM
-
- * ===================================
- * ===== _OBJC_DR : Object Draw =====
- * ===================================
- *
- * in: d0.w = start obj
- * d1.w = depth
- * a0.l = address of x,y,w,h clip limits [4 words]
- * a3.l = tree address
- * out: d0.w = 0 if error occurred
- *
- _objc_dr:
- lea int_in(a5),a1 ; address integer input array
- move.w d0,(a1)+ ; store starting object
- move.w d1,(a1)+ ; store drawing depth
- move.l (a0)+,(a1)+ ; store x and y
- move.l (a0)+,(a1)+ ; store w and h
- move.l a3,addr_in(a5) ; store address of resource tree
- moveq #OBJC_DRA,d1 ; set function code = object draw
- bra.s gem_ep ; call GEM
-
- * ======================================
- * ===== _FORM_DO : Process Dialog =====
- * ======================================
- *
- * in: d0.w = start object, a3.l = tree address
- * out: d0.w = exit object
- *
- _form_do:
- move.l a3,a0 ; pass tree address in A0
- moveq #FORM_DO,d1 ; function = FORM DO
- bra.s call_gem ; call GEM
-
- * ==========================================
- * ===== _FORM_DI : Dialog Housekeeping =====
- * ==========================================
- *
- * in: d0.w = action [0=reserve, 1=grow, 2=shrink, 3=free]
- * a0.l = address of x,y,w,h limits [4 words]
- * out: d0.w = 0 if an error occurred
- *
- * This routine is used to reserve or release memory or to draw a
- * growing or shrinking box. The operation code is passed in D0 and
- * the second x,y,w,h dimensions are pointed to by a0. This routine
- * is currently hard coded so that the first set of x,y,w,h points is
- * always zero.
- *
- _form_di:
- lea int_in(a5),a1 ; address integer input array
- move.w d0,(a1)+ ; store operation code
- clr.l (a1)+ ; x1 = 0, y1 = 0
- clr.l (a1)+ ; w1 = 0, h1 = 0
- move.l (a0)+,(a1)+ ; store x2, y2
- move.l (a0)+,(a1)+ ; store w2, h2
- moveq #FORM_DIA,d1 ; function = FORM_DIALOG
- bra.s gem_ep ; call GEM
-
- * ===========================================
- * ===== _FORM_AL : Process Alert Boxes =====
- * ===========================================
- *
- * in: d0.w = default exit button, a0 = alert string address
- * out: d0.w = exit button used, 1=first, 2=second, etc.
- *
- * This routine displays and processes user interaction with the alert
- * box. The address of the alert string is passed in A0 and the default
- * exit button if more than one is present is passed in D0. The
- * alternate entry point '_alert' sets the default exit button to 1.
- *
- _alert: moveq #1,d0 ; default exit button = 1 (leftmost)
- _form_al:
- moveq #FORM_ALE,d1 ; function code
- bra.s call_gem ; call GEM
-
- * ==============================================
- * ===== _FORM_CE : Calculate box centering =====
- * ==============================================
- *
- * in: a3.l = address of tree
- * a1.l = addr of area to store x,y,w,h of centered tree
- * out: none
- *
- * This routine calculates the x and y coordinates necessary to center
- * the resource treee addressed by A3 on the screen. The x,y,w,h
- * coordinates necessary for a clip rectangle are returned and stored
- * at the address passed in A1.
- *
- _form_ce:
- move.l a3,a0 ; pass tree address in A0
- moveq #FORM_CEN,d1 ; function = form center
- bsr.s call_gem ; call gem
- lea int_out+2(a5),a0 ; access x,y,w,h returned
- move.l (a0)+,(a1)+ ; store x,y
- move.l (a0)+,(a1)+ ; store w,h
- rts
-
- * ========================================
- * ===== _GRAF_MO : Change Mouse Form =====
- * ========================================
- *
- * in: d0.w = code of mouse form desired
- * out: d0.w = 0 if error
- * changed:
- *
- * This routine changes the form of the mouse pointer used. It can also
- * be used to hide and unhide the mouse.
- *
- _mouse: moveq #0,d0 set mouse form to pointer
- _graf_mo:
- suba.l a0,a0
- moveq #GRAF_MOU,d1
-
- * =======================================================
- * ===== call_gem : set up parameters for a gem call =====
- * =======================================================
- *
- * in: D1.W = op code number
- * D0.W = optional int_in[0]
- * A0.L = optional addr_in[0]
- * out: D0.W = returned value from int_out[0], if any
- * changed: A0,A1,D1
- *
- * This subroutine uses the op code number passed in D1 to
- * look up the number of integers and addresses in and out for the
- * GEM call. This information is then stored in the 'CONTROL' array
- * located in the dynamic storage area. Then GEM call is then
- * performed and a possible return code is loaded into D0 before exit.
- *
- call_gem:
- move.l a0,addr_in(a5) in case there's an address in
- move.w d0,int_in(a5) in case there's an integer in
-
- gem_ep: movem.l d2-d7/a1-a6,-(sp) ; save registers
- add.w d1,d1 ; function x 2
- add.w d1,d1 ; function x 4
- lea gemtbl(pc,d1.w),a0 ; form address of entry
- *
- * --- transfer opcode, integers in, integers out, and addresses
- *
- lea control(a5),a1 ; address control array
- moveq #0,d0 ; form a zero
- movep.l d0,0(a1) ; clear upper bytes of control[0..3]
- move.l (a0),d0 ; get bytes from table entry
- movep.l d0,1(a1) ; fill lower bytes of control[0..3]
- clr.w 8(a1) ; set control[4] to zero
- *
- * --- perform the GEM/AES call
- *
- move.l a5,d1 ; pass address of 'control' array in D1
- move.w #200,d0 ; pass special function number in D0
- trap #2 ; call the system
- movem.l (sp)+,d2-d7/a1-a6 ; restore registers
- moveq #0,d0 ; clear upper portion of register
- move.w int_out(a5),d0 ; retrieve a return value
- rts
- *
- * --- Table of control parameters for AES calls
- *
- * each entry has: AES/GEM function number
- * number of integers (words) in
- * number of integers (words) out
- * number of address (longs) in
- *
- gemtbl: dc.b 10,0,1,0 ; APPL_INIT
- dc.b 19,0,1,0 ; APPL_EXIT
- dc.b 42,6,1,1 ; OBJC_DRAW
- dc.b 50,1,1,1 ; FORM_DO
- dc.b 51,9,1,0 ; FORM_DIAL
- dc.b 52,1,1,1 ; FORM_ALERT
- dc.b 54,0,5,1 ; FORM_CENTER
- dc.b 78,1,1,1 ; GRAF_MOUSE
-
- *
- * --- strings for alerts
- *
- warning: dc.b '[3][ Clock missing or | not working ][ OK ]',0
- badtime: dc.b '[3][Bad Time or Date,|please retry][ OK ]',0
- *
- * --- strings for dialog
- *
- null: dc.b 0
-
- s_time: dc.b '122345A',0
- s1: dc.b 'TIME = __:__:__ _M',0
- s2: dc.b '999999F',0
-
- s_date: dc.b '071486',0
- s4: dc.b 'DATE = __/__/__',0
- s5: dc.b '999999',0
-
- s6: dc.b 'SUN',0
- s7: dc.b 'MON',0
- s8: dc.b 'TUE',0
- s9: dc.b 'WED',0
- s10: dc.b 'THU',0
- s11: dc.b 'FRI',0
- s12: dc.b 'SAT',0
-
- s13: dc.b 'SET',0
- s14: dc.b 'EXIT',0
- s15: dc.b 'CLOCK CARTRIDGE',0
- *
- * ========== text info structures ========== *
- *
- * each entry: L - pointer to text
- * L - pointer to template
- * L - pointer to validation string
- * W - font to be used, 3=normal, 5=small
- * W - 6
- * W - justification (left, center, right)
- * W - color code
- * W - 0
- * W - border thickness ( + outward, - inward )
- * W - length of text (including null)
- * W - length of template (including null)
- * =====
- * 28 bytes
- *
- *
- * --- text info blocks
- *
- ti0: dc.l s_time,s1,s2 ; time
- dc.w 3,6,0,$1180
- dc.w 0,-1,8,19
-
- ti1: dc.l s_date,s4,s5 ; date
- dc.w 3,6,0,$1180
- dc.w 0,-1,7,16
-
- ti2: dc.l s15,null,null ; title string
- dc.w 3,6,2,$1180
- dc.w 0,-3,16,1
- *
- * ========== object structures ========== *
- *
- * each entry: W - ID of next sibling (-1 if none)
- * W - ID of first offspring (-1 if none)
- * W - ID of last offspring (-1 if none)
- * W - type of object
- * W - object flags
- * W - state flags (selected, open, etc)
- * L - <expansion>
- * W - x position of upper left corner (relative to parent)
- * W - y position of upper left corner
- * W - width in pixels
- * W - height in pixels
- * =====
- * 24 bytes
- *
- * --- object types:
- *
- BOX EQU 20 ; box
- TXT EQU 21 ; text
- BOXTEXT EQU 22 ; text within a box
- IMAGE EQU 23 ; bit image
- PROGDEF EQU 24 ; programmer defined
- IBOX EQU 25 ; invisible box
- BUTTON EQU 26 ; text within a button
- BOXCHAR EQU 27 ; single char within a button
- STRING EQU 28 ; string
- ETEXT EQU 29 ; editable text
- EBOXTEXT EQU 30 ; editable text within a box
- ICON EQU 31 ; icon image
- TITLE EQU 32 ; string used in menu titles
- *
- * --- object option flags:
- *
- NONE EQU $0000 ; no option
- SLECTBLE EQU $0001 ; SLECTBLE
- DEFAULT EQU $0002 ; default for <CR>
- EXIT EQU $0004 ; causes exit when selected
- EDITABLE EQU $0008 ; editable text
- RADIOB EQU $0010 ; radio button
- LASTOB EQU $0020 ; last object in tree
- *
- * --- object states:
- *
- NORMAL EQU $0000 ; nothing special
- SELECTED EQU $0001 ; has been selected by the mouse button
- DISABLED EQU $0008 ; can't be selected
- OUTLINED EQU $0010 ; shows up as outlined
- SHADOWED EQU $0020 ; shows up as casting a shadow
- *
- * ===== RESOURCE TREE: ================================================
- *
- tree: dc.w -1,01,01,BOX ; outermost box
- dc.w NONE,NORMAL
- dc.l $00011100
- dc.w 0,0,262,174
- * obj 1
- dc.w 00,02,14,BOX
- dc.w SLECTBLE+EXIT,NORMAL ; inner framing box
- dc.l $00FD1103
- dc.w 7,7,248,160
- * obj 2
- dc.w 03,-1,-1,ETEXT ; editable date string
- dc.w EDITABLE,NORMAL
- dc.l ti1
- dc.w 79,55,120,16
- * obj 3
- dc.w 04,-1,-1,ETEXT ; editable time string
- dc.w EDITABLE,NORMAL
- dc.l ti0
- dc.w 79,78,144,16
- * obj 4
- dc.w 12,05,11,BOX ; box surrounding radio buttons
- dc.w NONE,NORMAL
- dc.l $00FF1100
- dc.w 16,16,43,126
- * obj 5
- dc.w 06,-1,-1,BUTTON ; radio button for SUN
- dc.w (RADIOB+SLECTBLE),NORMAL
- dc.l s6
- dc.w 1,1,41,16
- * obj 6
- dc.w 07,-1,-1,BUTTON ; MON
- dc.w (RADIOB+SLECTBLE),NORMAL
- dc.l s7
- dc.w 1,19,41,16
- * obj 7
- dc.w 08,-1,-1,BUTTON ; TUE
- dc.w (RADIOB+SLECTBLE),NORMAL
- dc.l s8
- dc.w 1,37,41,16
- * obj 8
- dc.w 09,-1,-1,BUTTON ; WED
- dc.w (RADIOB+SLECTBLE),NORMAL
- dc.l s9
- dc.w 1,55,41,16
- * obj 9
- dc.w 10,-1,-1,BUTTON ; THU
- dc.w (RADIOB+SLECTBLE),NORMAL
- dc.l s10
- dc.w 1,73,41,16
- * obj 10
- dc.w 11,-1,-1,BUTTON ; FRI
- dc.w (RADIOB+SLECTBLE),NORMAL
- dc.l s11
- dc.w 1,91,41,16
- * obj 11
- dc.w 04,-1,-1,BUTTON ; SAT
- dc.w (RADIOB+SLECTBLE),NORMAL
- dc.l s12
- dc.w 1,109,41,16
- * obj 12
- dc.w 13,-1,-1,BUTTON ; 'SET' button
- dc.w 5,SHADOWED
- dc.l s13
- dc.w 72,112,64,16
- * obj 13
- dc.w 14,-1,-1,BUTTON ; 'EXIT' button
- dc.w 5,SHADOWED
- dc.l s14
- dc.w 160,112,64,16
- * obj 14
- dc.w 01,-1,-1,BOXTEXT ; title in a box
- dc.w LASTOB+SLECTBLE+EXIT,NORMAL
- dc.l ti2
- dc.w 80,16,136,16
- *
- * --- dynamic storage area begins at end of program
- *
- * The dynamic storage is an uninitialized temporary data area that
- * begins at the end of the program. It is used for the stack and all
- * variables that do not need to be initialized prior to program
- * execution. Use of a dynamic storage area reduces the disk space
- * requirements of the program.
- *
- storage: nop
- end
-